package com.ybkj.o2o.mc.common;

import com.ybkj.o2o.mc.entity.Enterprise;
import com.ybkj.o2o.mc.entity.Passenger;
import com.ybkj.o2o.mc.entity.PassengerAccount;
import com.ybkj.o2o.mc.entity.PassengerAddress;
import com.ybkj.o2o.mc.entity.PassengerConcats;
import com.ybkj.o2o.mc.entity.PassengerGrade;
import com.ybkj.o2o.mc.service.EnterpriseService;
import com.ybkj.o2o.mc.service.PassengerAccountService;
import com.ybkj.o2o.mc.service.PassengerAddressService;
import com.ybkj.o2o.mc.service.PassengerConcatsService;
import com.ybkj.o2o.mc.service.PassengerService;

import org.apache.commons.lang.StringUtils;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

public class ImportTask implements Runnable {

  private PassengerGrade gradecommon;

  private PassengerGrade gradevip;

  private EnterpriseService enterpriseService;

  private List<Map<String, String>> companyMapList;

  private Map<String, Object> rs;

  private Connection connection;

  private String appKey;

  private List<String> blackList;

  private PassengerService passengerService;

  private PassengerConcatsService passengerConcatsService;

  private PassengerAddressService passengerAddressService;

  private PassengerAccountService passengerAccountService;

  private AtomicInteger atomicInteger;

  /**
   * 创建导入任务.
   */
  public ImportTask(PassengerGrade gradecommon, PassengerGrade gradevip,
                    EnterpriseService enterpriseService, List<Map<String, String>> companyMapList,
                    Map<String, Object> rs, Connection connection, String appKey,
                    List<String> blackList, PassengerService passengerService,
                    PassengerConcatsService passengerConcatsService,
                    PassengerAddressService passengerAddressService,
                    PassengerAccountService passengerAccountService, AtomicInteger atomicInteger) {

    this.gradecommon = gradecommon;
    this.gradevip = gradevip;
    this.enterpriseService = enterpriseService;
    this.companyMapList = companyMapList;
    this.rs = rs;
    this.connection = connection;
    this.appKey = appKey;
    this.blackList = blackList;
    this.passengerService = passengerService;
    this.passengerConcatsService = passengerConcatsService;
    this.passengerAddressService = passengerAddressService;
    this.passengerAccountService = passengerAccountService;
    this.atomicInteger = atomicInteger;
  }

  @Override
  public void run() {
    try {
      atomicInteger.incrementAndGet();

      final Long id = (Long) rs.get("id");
      Date created = (Date) rs.get("created");
      Date updated = (Date) rs.get("updated");
      String type = (String) rs.get("type");

      String name = (String) rs.get("name");
      if (StringUtils.isBlank(name)) {
        name = "先生/女士";
      }
      String photo = (String) rs.get("photo");
      String idCard = (String) rs.get("idCard");
      String email = (String) rs.get("email");
      String agencyName = (String) rs.get("agencyName");
      String agencyAddress = (String) rs.get("agencyAddress");
      String fromSource = (String) rs.get("fromSource");
      Boolean isOverdraw = (Boolean) rs.get("isOverdraw");
      String memo = (String) rs.get("memo");
      BigDecimal alreadyMoney = (BigDecimal) rs.get("alreadyMoney");
      BigDecimal virtual = (BigDecimal) rs.get("virtual");
      Double longitude = (Double) rs.get("longitude");
      Double latitude = (Double) rs.get("latitude");
      Long companyId = (Long) rs.get("company_id");
      String appVersion = (String) rs.get("appVersion");
      Long completeTimes = (Long) rs.get("completeTimes");
      Integer introduceType = (Integer) rs.get("introduceType");
      String introducer = (String) rs.get("introducer");
      Long areaId = (Long) rs.get("areaId");
      Long areaCarId = (Long) rs.get("areaCarId");


      String companyName = "";

      for (Map<String, String> map : companyMapList) {
        if (companyId.equals(Long.parseLong(map.get("id")))) {
          companyName = map.get("name");
          break;
        }
      }

      Enterprise enterprise = new Enterprise();
      if ("企业用户".equals(type)) {
        enterprise.setName(agencyName);
        enterprise.setAddress(agencyAddress);
        enterprise.setMemo(memo);
        enterprise.setAllowOverdraw(isOverdraw);
        enterprise.setGradeId(gradecommon.getId());
        enterprise.setGradeName(gradecommon.getName());
        enterprise.setCompanyId(companyId);
        enterprise.setCompanyName(companyName);
        enterprise.setDrawMoney(virtual.doubleValue());
        enterprise.setNodrawMoney(0d);
        enterprise.setFrozenMoney(0d);
        enterprise.setDrivingNumberTimes(completeTimes);
        enterprise.setCreated(created);
        enterprise.setUpdated(updated);
        enterprise.setVersion(1);
        enterprise.setAppKey(appKey);
        enterpriseService.insert(enterprise);
      }

      String sql = "select * from dj_member_account where member_id=?";

      PreparedStatement pstmt = connection.prepareStatement(sql);
      pstmt.setLong(1, id);
      ResultSet accountRs = pstmt.executeQuery();

      Passenger firstPassenger = null;
      while (accountRs.next()) {

        String accountName = accountRs.getString("name");
        final String gender = accountRs.getString("gender");
        String phone = accountRs.getString("phone");
        String memberEcn = accountRs.getString("memberEcn");
        final String memberEcp = accountRs.getString("memberEcp");
        final String address = accountRs.getString("address");
        final Double addressLng = accountRs.getDouble("addressLng");
        final Double addressLat = accountRs.getDouble("addressLat");
        final String carNumber = accountRs.getString("carNumber");
        final String cid = accountRs.getString("cid");
        final String deviceType = accountRs.getString("deviceType");
        final Date accountCreated = accountRs.getDate("created");
        final Date accountUpdated = accountRs.getDate("updated");
        Passenger passenger = new Passenger();
        passenger.setName(accountName);
        passenger.setPhone(phone);
        passenger.setAllowOverdraw(isOverdraw);

        if ("企业用户".equals(type)) {
          passenger.setEnterpriseId(enterprise.getId());
          passenger.setEnterpriseName(enterprise.getName());
          passenger.setGradeId(gradecommon.getId());
          passenger.setGradeName(gradecommon.getName());
          passenger.setType(1);
        } else {
          if (null != virtual) {
            passenger.setDrawMoney(virtual.doubleValue());
          } else {
            passenger.setDrawMoney(0d);
          }
          passenger.setNodrawMoney(0d);
          passenger.setFrozenMoney(0d);
          if (null != alreadyMoney) {
            passenger.setReceiptMoney(alreadyMoney.doubleValue());
          } else {
            passenger.setReceiptMoney(0d);
          }
          passenger.setType(0);
          if ("个人用户".equals(type)) {
            passenger.setGradeId(gradecommon.getId());
            passenger.setGradeName(gradecommon.getName());
          } else if ("VIP用户".equals(type)) {
            passenger.setGradeId(gradevip.getId());
            passenger.setGradeName(gradevip.getName());
          }
          passenger.setMemo(memo);
        }

        boolean isBlackList = false;
        if (!CollectionUtils.isEmpty(blackList)) {
          for (String blackPhone : blackList) {
            if (blackPhone.equals(phone)) {
              isBlackList = true;
              break;
            }
          }
        }
        passenger.setInBlackList(isBlackList);

        passenger.setPlateNumber(carNumber);
        passenger.setPhoto(photo);
        passenger.setIdcard(idCard);
        if (StringUtils.isNotBlank(gender)) {
          if ("先生".equals(gender)) {
            passenger.setGender(0);
          } else if ("女士".equals(gender)) {
            passenger.setGender(1);
          }
        }
        passenger.setEmail(email);
        passenger.setLatitude(latitude);
        passenger.setLongitude(longitude);
        passenger.setAddress(address);
        passenger.setDrivingNumberTimes(completeTimes);
        passenger.setDeviceType(deviceType);
        passenger.setCreated(accountCreated);
        passenger.setUpdated(accountUpdated);
        passenger.setVersion(1);
        passenger.setChannelName(fromSource);
        passenger.setAppKey(appKey);
        passenger.setCompanyId(companyId);
        passenger.setCompanyName(companyName);
        passenger.setIntroducer(introducer);
        passenger.setIntroduceType(introduceType);
        passenger.setAppVersion(appVersion);

        passengerService.insert(passenger);

        if (accountRs.isFirst()) {
          firstPassenger = passenger;
        }

        //紧急联系人
        if (StringUtils.isNotBlank(memberEcp)) {
          PassengerConcats passengerConcats = new PassengerConcats();
          passengerConcats.setName(memberEcn);
          passengerConcats.setPhone(memberEcp);
          passengerConcats.setPassengerId(passenger.getId());
          passengerConcats.setCreated(new Date());
          passengerConcats.setUpdated(new Date());
          passengerConcatsService.insert(passengerConcats);
        }

        //常用地址
        if (StringUtils.isNotBlank(address) && null != addressLat && null != addressLng) {
          PassengerAddress passengerAddress = new PassengerAddress();
          passengerAddress.setAddress(address);
          passengerAddress.setLatitude(addressLat);
          passengerAddress.setLongitude(addressLng);
          passengerAddress.setType(2);
          passengerAddress.setPassengerId(passenger.getId());
          passengerAddress.setCreated(new Date());
          passengerAddress.setUpdated(new Date());
          passengerAddress.setVersion(1);
          passengerAddressService.insert(passengerAddress);
        }

        Long accountId = passenger.getId();

        //推送id
        if (StringUtils.isNotBlank(cid)) {
          sql = "insert into dj_passenger_gexin (`passenger_id`, `c_id`) values (?,?)";
          PreparedStatement statement = connection.prepareStatement(sql);
          statement.setLong(1, accountId);
          statement.setString(2, cid);
          statement.executeUpdate();
          if (statement != null) {
            statement.close();
            statement = null;
          }
        }
        //代驾收费
        if (null != areaId) {
          sql = "insert into dj_passenger_fee_daijia (`passenger_id`, `area_id`) values (?, ?)";
          PreparedStatement statement = connection.prepareStatement(sql);
          statement.setLong(1, accountId);
          statement.setLong(2, areaId);
          statement.executeUpdate();
          if (statement != null) {
            statement.close();
            statement = null;
          }
        }
        //专车收费
        if (null != areaCarId) {
          sql = "insert into dj_passenger_fee_zhuanche (`passenger_id`, `area_id`) values (?, ?)";
          PreparedStatement statement = connection.prepareStatement(sql);
          statement.setLong(1, accountId);
          statement.setLong(2, areaCarId);
          statement.executeUpdate();
          if (statement != null) {
            statement.close();
            statement = null;
          }
        }

        if (StringUtils.isNotBlank(phone)) {
          updateRelInfo(phone, accountId);
        }
      }

      if (null != accountRs) {
        accountRs.close();
        accountRs = null;
      }
      if (pstmt != null) {
        pstmt.close();
        pstmt = null;
      }

      //财务记录
      sql = "select * from dj_member_payments_record where member_id=?";
      pstmt = connection.prepareStatement(sql);
      pstmt.setLong(1, id);
      ResultSet caiwuRs = pstmt.executeQuery();
      while (caiwuRs.next()) {
        final Double money = caiwuRs.getDouble("money");
        final Double afterMoney = caiwuRs.getDouble("afterMoney");
        final String orderNumber = caiwuRs.getString("orderNumber");
        final Long orderId = caiwuRs.getLong("orderId");
        final String paymentType = caiwuRs.getString("paymentType");
        final String paymentMemo = caiwuRs.getString("memo");
        final String operating = caiwuRs.getString("operating");
        final String tradeNo = caiwuRs.getString("tradeNo");
        final Date paymentCreated = caiwuRs.getDate("created");
        final Date paymentUpdated = caiwuRs.getDate("updated");
        
        PassengerAccount passengerAccount = new PassengerAccount();
        if ("企业用户".equals(type)) {
          passengerAccount.setEnterpriseId(enterprise.getId());
          passengerAccount.setEnterpriseName(enterprise.getName());
        } else {
          sql = "select phone from dj_member_account where member_id=? limit 0,1";
          pstmt = connection.prepareStatement(sql);
          pstmt.setLong(1, id);
          ResultSet paymentAccountRs = pstmt.executeQuery();
          while (paymentAccountRs.next()) {
            
            String phone = paymentAccountRs.getString("phone");
            
            Passenger local = passengerService.findByPhoneAndAppKey(phone, appKey);
            if (null != local) {
              passengerAccount.setPassengerId(local.getId());
              passengerAccount.setPassengerName(local.getName());
              passengerAccount.setPassengerPhone(local.getPhone());
            }
          }
          if (null != paymentAccountRs) {
            paymentAccountRs.close();
            paymentAccountRs = null;
          }
          if (pstmt != null) {
            pstmt.close();
            pstmt = null;
          }
        }

        passengerAccount.setMoney(money);
        passengerAccount.setAfterDrawMoney(afterMoney);
        passengerAccount.setAfterNoDrawMoney(0d);
        passengerAccount.setAfterFrozenMoney(0d);
        passengerAccount.setOrderNo(orderNumber);
        passengerAccount.setOrderId(orderId);
        passengerAccount.setOrderType(0);
        passengerAccount.setPayType(paymentType);
        passengerAccount.setDetails(paymentMemo);
        passengerAccount.setOperator(operating);
        passengerAccount.setTradeNo(tradeNo);
        passengerAccount.setAppKey(appKey);
        passengerAccount.setCompanyId(companyId);
        passengerAccount.setCreated(paymentCreated);
        passengerAccount.setUpdated(paymentUpdated);
        passengerAccount.setVersion(1);

        passengerAccountService.insert(passengerAccount);
      }
      if (null != caiwuRs) {
        caiwuRs.close();
        caiwuRs = null;
      }
      if (pstmt != null) {
        pstmt.close();
        pstmt = null;
      }

      //优惠券
      pstmt = connection.prepareStatement("select * from dj_coupon where member_id=?");
      pstmt.setLong(1, id);
      ResultSet rsCoupon = pstmt.executeQuery();
      while (rsCoupon.next()) {
        String phone = (String) rs.get("phone");
        if (StringUtils.isNotBlank(phone)) {
          Passenger passenger = passengerService.findByPhoneAndAppKey(phone, appKey);
          if (null != passenger) {
            sql = "update dj_activity_record set member_id=? where phone=?";
            PreparedStatement couponPstmt = connection.prepareStatement(sql);
            couponPstmt.setLong(1, passenger.getId());
            couponPstmt.setString(2, phone);
            couponPstmt.executeUpdate();
            if (couponPstmt != null) {
              couponPstmt.close();
              couponPstmt = null;
            }
          }
        } else {
          if (null != firstPassenger) {
            sql = "update dj_activity_record set member_id=? where member_id=?";
            PreparedStatement couponPstmt = connection.prepareStatement(sql);
            couponPstmt.setLong(1, firstPassenger.getId());
            couponPstmt.setLong(2, id);
            couponPstmt.executeUpdate();
            if (couponPstmt != null) {
              couponPstmt.close();
              couponPstmt = null;
            }
          }
        }
      }
      if (null != rsCoupon) {
        rsCoupon.close();
        rsCoupon = null;
      }
      if (pstmt != null) {
        pstmt.close();
        pstmt = null;
      }
    } catch (Exception ex) {
      ex.printStackTrace();
      throw new RuntimeException(ex);
    }
  }

  /**
   * 更新关联数据.
   */
  private void updateRelInfo(String phone, Long accountId) throws SQLException {
    Statement statement = connection.createStatement();
    String sql;
    if (statement != null) {

      sql = getUpdateSql("dj_activity_record", "member_id", accountId, "phone", phone);
      statement.addBatch(sql);

      sql = getUpdateSql("dj_feedback", "memberID", accountId, "phone", phone);
      statement.addBatch(sql);

      sql = getUpdateSql("dj_order", "clientId", accountId, "clientPhone", phone);
      statement.addBatch(sql);

      sql = getUpdateSql("dj_order_finished_info", "clientId", accountId, "clientPhone", phone);
      statement.addBatch(sql);

      sql = getUpdateSql("dj_phone_record", "memberId", accountId, "memberPhone", phone);
      statement.addBatch(sql);

      sql = getUpdateSql("dj_phonevisit", "memberId", accountId, "phone", phone);
      statement.addBatch(sql);

      sql = getUpdateSql("dj_rate", "memberId", accountId, "memberPhone", phone);
      statement.addBatch(sql);

      sql = getUpdateSql("dj_receipt", "member_id", accountId, "memberPhone", phone);
      statement.addBatch(sql);

      sql = getUpdateSql("dj_rentorder", "clientId", accountId, "clientPhone", phone);
      statement.addBatch(sql);

      sql = getUpdateSql("dj_share_record", "memberId", accountId, "phone", phone);
      statement.addBatch(sql);

      sql = getUpdateSql("dj_usually_driver", "memberId", accountId, "phone", phone);
      statement.addBatch(sql);

      statement.executeBatch();

      statement.close();
      statement = null;
    }
  }

  private String getUpdateSql(String tableName, String col1Name,
                              Long col1Value, String col2Name, String col2Value) {

    StringBuilder sb = new StringBuilder();
    sb.append("update ").append(tableName).append(" ");
    sb.append("set ").append(col1Name).append("='").append(col1Value).append("' ");
    sb.append("where ").append(col2Name).append("='").append(col2Value).append("'");
    return sb.toString();
  }

}